package com.ibox.utils;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.ibox.BaseApplication;

import org.reactivestreams.Publisher;

import java.lang.reflect.Field;
import java.util.List;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.FlowableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

import static android.R.attr.data;

/**
 * Project IBox
 * Created by Amos
 * Created on 2017-10-12
 * Desc
 */

public class RxUtils {

    /**
     * 从缓存中读取数据
     *
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> Flowable<Object> readFlowableFromeCache(final String key, final Class<T> clazz) {
        return Flowable.create(new FlowableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull FlowableEmitter e) throws Exception {
                LogUtils.d("get data from disk: key==" + key);
                String json = ACache.get(BaseApplication.getInstance()).getAsString(key);
                LogUtils.d("get data from disk finish , json==" + json);
                if (!TextUtils.isEmpty(json)) {
                    e.onNext(json);
                }
                e.onComplete();
            }
        }, BackpressureStrategy.BUFFER).map(new Function<String, Object>() {
            @Override
            public Object apply(@NonNull String s) throws Exception {
                return new Gson().fromJson(s, clazz);
            }
        }).subscribeOn(Schedulers.io());
    }

    /**
     * 缓存列表类型数据
     *
     * @param key
     * @param <T>
     * @return
     */
    public static <T> FlowableTransformer<T, T> cacheListData(final String key) {
        return new FlowableTransformer<T, T>() {
            @Override
            public Publisher<T> apply(@NonNull Flowable<T> upstream) {
                return upstream.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .doOnNext(new Consumer<T>() {
                            @Override
                            public void accept(final T t) throws Exception {
                                Schedulers.io().createWorker().schedule(new Runnable() {
                                    @Override
                                    public void run() {
                                        LogUtils.d("get data from network finish ,start cache...");
                                        if (t == null) return;
                                        Field[] fields = t.getClass().getFields();
                                        for (Field field : fields) {
                                            String className = field.getType().getSimpleName();
                                            if (className.equalsIgnoreCase("List")) {
                                                try {
                                                    List list = (List) field.get(t);
                                                    LogUtils.d("list==" + list);
                                                    if (list != null && !list.isEmpty()) {
                                                        ACache.get(BaseApplication.getInstance())
                                                                .put(key, new Gson().toJson(data, t.getClass()));
                                                        LogUtils.d("cache finish");
                                                    }
                                                } catch (IllegalAccessException e) {
                                                    e.printStackTrace();
                                                }
                                            }
                                        }
                                    }
                                });
                            }
                        });
            }
        };
    }

    /**
     * 缓存bean类型数据
     *
     * @param key
     * @param <T>
     * @return
     */
    public static <T> FlowableTransformer<T, T> cacheBeanData(final String key) {
        return new FlowableTransformer<T, T>() {
            @Override
            public Publisher<T> apply(@NonNull Flowable<T> upstream) {
                return upstream.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .doOnNext(new Consumer<T>() {
                            @Override
                            public void accept(final T t) throws Exception {
                                Schedulers.io().createWorker().schedule(new Runnable() {
                                    @Override
                                    public void run() {
                                        LogUtils.d("get data from network finish ,start cache...");
                                        ACache.get(BaseApplication.getInstance())
                                                .put(key, new Gson().toJson(data, t.getClass()));
                                        LogUtils.d("cache finish");
                                    }
                                });
                            }
                        });
            }
        };
    }
}
